package singleton;

import android.annotation.SuppressLint;
import android.util.Log;

import java.lang.reflect.Constructor;
import java.util.concurrent.ConcurrentHashMap;

import baseinterface.BaseInterface;

/**
 * Created by Administrator on 2017/5/14.
 */
public class SingletonClass {

    /** 存放单例对象 */
    @SuppressLint("NewApi")
    private static final ConcurrentHashMap<Class, Object> singletonInstanceMap = new ConcurrentHashMap<Class, Object>(
            200, 0.75f);

    /**
     * 简单获取单例对象
     *
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T getSingleton(Class<T> clazz) {
        return getSingleton(clazz, null, null);
    }

    /**
     * 获取单例对象
     *
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T getSingleton(Class<T> clazz, Class<T>[] argClazz, Object[] args) {
        if (!BaseInterface.class.isAssignableFrom(clazz)) {
            Log.e("SingletonClass", "[GETBEAN]not ISingleable bean ---> " + clazz.getName());
            return null;
        }
        Object instance = singletonInstanceMap.get(clazz);
        if (instance == null) {
            synchronized (clazz) {
                instance = singletonInstanceMap.get(clazz);
                if (instance == null) {
                    try {
                        if (argClazz == null) {
                            instance = clazz.newInstance();
                        } else {
                            Constructor<T> constructor = clazz.getDeclaredConstructor(argClazz);
                            constructor.setAccessible(true);
                            instance = constructor.newInstance(args);
                        }
                        singletonInstanceMap.put(clazz, instance);
                        Log.e("SingletonClass", "[GETBEAN]newInstance Class ---> " + clazz.getName());

                    } catch (Exception e) {
                        Log.e("SingletonClass", "[GETBEAN]newInstance error ---> " + clazz.getName());
                        e.printStackTrace();
                    }
                }
            }
        }

        return (T) instance;
    }
}
